package com.nervenets.web.controller.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.nervenets.utils.HttpTools;
import com.nervenets.utils.NumberUtil;
import com.nervenets.web.controller.Global;
import com.nervenets.web.controller.handler.common.TokenParams;
import com.nervenets.web.entity.MessageCode;
import com.nervenets.web.enumeration.Method;
import com.nervenets.web.enumeration.Role;
import com.nervenets.web.hibernate.domain.SystemLog;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.ServletRequestUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;

/**
 * 继承于此Handler的接口属于必须要登录的接口，也会限制权限
 * Created by joe on 17-3-27.
 */
public abstract class SessionHandler<T extends ApiParams> extends Handler<T> {
    @Override
    public String handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String token = ServletRequestUtils.getStringParameter(request, "token");
        if (StringUtils.isEmpty(token)) return errorMessage(MessageCode.code_444, "token不合法");
        long sessionUserId = TokenParams.resolveToken(token);
        if (-1 == sessionUserId) return errorMessage(MessageCode.code_777);
        String loginSessionValue = globalVariablesService.getSession(sessionUserId, Global.Constants.SESSION_USER_ROLE);
        if (StringUtils.isEmpty(loginSessionValue)) return errorMessage(MessageCode.code_777);
        JSONObject sessionUserRole = JSON.parseObject(loginSessionValue);
        final ArrayList<Role> roles = allowRoles();
        boolean allowed = false;
        if (null != roles && !roles.isEmpty()) {
            for (Role role : roles) {
                if (sessionUserRole.getBoolean(role.name())) {
                    allowed = true;
                    break;
                }
            }
            if (!allowed) return errorMessage(MessageCode.code_503, roles);
        }
        final String result = super.handleRequest(request, response);
        try {
            if (needLog()) {
                String method = StringUtils.trimAllWhitespace(ServletRequestUtils.getStringParameter(request, "method"));
                userDao.saveOrUpdate(new SystemLog(sessionUserId, Method.valueOf(method), com.nervenets.utils.StringUtils.toJsonNotUnicode(getParams()), result, NumberUtil.ipToLong(HttpTools.getIpAddress(request))));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public abstract ArrayList<Role> allowRoles();

    public abstract boolean needLog();

    @Override
    public boolean isAuthority() {
        final ArrayList<Role> roles = allowRoles();
        return null != roles && !roles.isEmpty();
    }

    public ArrayList<Role> getRoles() {
        return allowRoles();
    }
}
